package com.dosin.crowno;

import com.alibaba.fastjson.JSONObject;
import com.dosin.crowno.controller.*;
import com.dosin.crowno.events.LoginStatusEvent;
import com.dosin.crowno.events.SpiderOrderEvent;
import com.dosin.crowno.models.SettingInfo;
import com.dosin.crowno.models.UserInfo;
import com.dosin.crowno.pojo.UserAccount;
import com.dosin.crowno.service.MainService;
import com.dosin.crowno.service.UserAccountService;
import com.dosin.crowno.utils.*;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.collections.FXCollections;
import javafx.concurrent.Worker;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebErrorEvent;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import javafx.stage.Window;
import javafx.stage.WindowEvent;
import lombok.extern.slf4j.Slf4j;
import netscape.javascript.JSObject;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSessionContext;
import java.io.IOException;
import java.net.*;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;

@Slf4j
@Component
public class MainController implements Initializable {

    @Resource
    UserAccountService userAccountService;

    @Resource
    private ReadProjectController readProjectController;

    @Resource
    private ScreenController screenController;

    @Resource
    private SoundController soundController;

    @Resource
    private NetaddrController netaddrController;

    @Resource
    private LoginsetuprController loginsetupbuttonAction;

    @Resource
    private LogsetuprController logsetupbuttonAction;

    @Resource
    private PhonesendController phonesendController;

    @Resource
    MainService mainService;


    @FXML
    private Label usernameText;

    @FXML
    private Label daoqidateText;

    @FXML
    private Label versionText;


    @FXML
    private ChoiceBox ipChoiceText;

    @FXML
    private ChoiceBox portChoiceText;

    @FXML
    private ChoiceBox websiteChoiceText;

    @FXML
    private ChoiceBox levelSelect;

    @FXML
    private Button netLoginButton;

    @FXML
    private TextField userTextField;

    @FXML
    private TextField netPasswordText;

    @FXML
    private TextField safetyCodeTextField;

    @FXML
    WebView webView;

    private String uId;

    /**
     * 登录状态检测线程
     */
    private Thread loginThread;

    private Thread spiderThread;

    /**
     * 读取可切换的网址(todo 从数据库或者配置读取)
     * @return
     */
    private String getUrl(){
        return "https://ag.hga008.com/";
    }

    /**
     * 读取当前代理账号信息(todo 从数据库或者配置读取)
     * @return
     */
    private UserInfo getAgent(){
        return new UserInfo("cs1213","Aabb1122","");
       // return new UserInfo("gao444","Asd123456","AAbb1122");
    }

    /**
     * 读取当前代理设置信息(todo 从数据库或者配置读取)
     * @return
     */
    private SettingInfo getSetting(){
        SettingInfo settingInfo= new SettingInfo();
        settingInfo.setSpiderStatusInterval(1000*2);
        settingInfo.setLoginStatusInterval(1000*5);
        return settingInfo;
    }



    //打开主页面
    protected void openMainWindow(UserAccount user, TextField usernameTextField) throws IOException {

        Stage mainStage = new Stage();
        mainStage.setScene(new Scene(CrownoApplication.loadFxml("/server.fxml").load()));

        System.out.println(getClass().getResource("/images").toString());
        mainStage.getIcons().add( new Image(getClass().getResource("/images/crownt.png").toString()));
        mainStage.setTitle("新皇冠（服务端）1.1.1.0 - 服务端口：1111 - 服务密码：88888");
        usernameText.setText(user.getUsername());
        SimpleDateFormat sf  = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        daoqidateText.setText(sf.format(user.getDueDate()));
        if(user.getVersion()==0){
        versionText.setText("正式");
        }else if(user.getVersion() ==1){
            versionText.setText("测试");
        }else{
            versionText.setText("临时用户");
        }



/*        https://ag.hga008.com
        https://ag.hga025.com
        https://ag.hga030.com
        https://ag.hga0088.com*/

        List list = new ArrayList();
        List ips = new ArrayList();
        List levels = new ArrayList();
        list.add("https://ag.hga008.com");
        list.add("https://ag.hga025.com");
        list.add("https://ag.hga030.com");
        list.add("https://ag.hga0088.com");
        levels.add(1);
        levels.add(2);
        levels.add(3);
        ips.add("127.0.0.1");

        ipChoiceText.setItems(FXCollections.observableArrayList(ips));
        ipChoiceText.setValue(ips.get(0));


        portChoiceText.setItems(FXCollections.observableArrayList(1111));
        portChoiceText.setValue(1111);



        websiteChoiceText.setItems(FXCollections.observableArrayList(list));
        websiteChoiceText.setValue(list.get(0));

        levelSelect.setItems(FXCollections.observableArrayList(levels));
        levelSelect.setValue(levels.get(2));

        mainStage.show();





        Window window = usernameTextField.getScene().getWindow();
        if(window instanceof Stage){
            ((Stage) window).close();
        }






        mainStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
            @Override
            public void handle(WindowEvent event) {
                System.out.print("监听到窗口关闭");
                user.setIsLogin(0);
                userAccountService.updateByPrimaryKeySelective(user);
                System.exit(0);
            }
        });
    }




    /**
     * 检测登录状态事件
     * @param event
     */
    @Subscribe(threadMode = ThreadMode.BACKGROUND)
    public void onLoginSuccessEvent(LoginStatusEvent event) {
        //更新JavaFX的主线程的代码放在此处
        Platform.runLater(()->{
            WebEngine webEngine = webView.getEngine();
            JSObject window = (JSObject) webEngine.executeScript("window");
            String value=window.getMember("uid").toString();
            //String value="2041e33dm7501775l23528354";
            System.out.println("onLoginSuccessEvent:"+value);
            if(value!=null&&!"".equals(value)&&!"undefined".equals(value)){
                System.out.println("uid value:"+value);
                uId=value;
            }
        });
    };

    /**
     * 抽取订单数据事件
     * @param event
     */
    @Subscribe(threadMode = ThreadMode.BACKGROUND)
    public void onSpiderOrderEvent(SpiderOrderEvent event) {
        Platform.runLater(()->{
            System.out.println("spider data:"+event.getData().toJSONString());
        });
    };

    /**
     * 打开登录页
     */
    public void openButtonAction(){
        //WebEngine webEngine = webView.getEngine();
        WebEngine webEngine = webView.getEngine();
        webEngine.setUserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36");
        webEngine.setJavaScriptEnabled(true);
        webEngine.setOnError(new EventHandler<WebErrorEvent>() {
            @Override
            public void handle(WebErrorEvent webErrorEvent) {
                System.out.println(webErrorEvent.getMessage());
            }
        });
        webEngine.load(getUrl());
        webEngine.getLoadWorker().stateProperty().addListener(
                (ChangeListener) (observable, oldValue, newValue) -> {
                    System.out.println("oldvalue:"+oldValue+",newvalue:"+newValue);

                    Throwable throwable= webEngine.getLoadWorker().getException();
                    String message=webEngine.getLoadWorker().getMessage();

                    if (newValue != Worker.State.SUCCEEDED) { return; }

                }
        );
    }
    /**
     * 登录
     */
    public void netLoginButtonAction(){
        WebEngine webEngine = webView.getEngine();
        UserInfo curAgent=getAgent();
        String script="function HttpRequest(){\n" +
                "\t\tvar self=this;\n" +
                "\t\tvar req;\n" +
                "\t\tvar eventHandler=new Array();\n" +
                "\t\tvar parentClass;\n" +
                "\t\t\n" +
                "\t\tself.init=function(){\n" +
                "\t\t\t\tself.addEventListener(\"LoadComplete\",self.cmd_proc);\n" +
                "\t\t\t\t//self.removeEventListener(\"LoadComplete\");\n" +
                "\t\t\t\t//alert(\"onload\");\n" +
                "\t\t\t\t}\n" +
                "\t\tself.help=function(){\n" +
                "\t\t\t\tvar str=\"\";\n" +
                "\t\t\t\tstr+=\"EventName:LoadComplete Method:function(html)\\n\";\n" +
                "\t\t\t\tstr+=\"Method:loadURL(url,post/get,pamam)\\n\";\n" +
                "\t\t\t\treturn str;\n" +
                "\t\t}\n" +
                "\t\t\n" +
                "\t\tself.setParentclass=function(parentclass){\n" +
                "\t\t\t\tparentClass=parentclass;\n" +
                "\t\t\t\t//util=parentClass.util;\n" +
                "\t\t}\n" +
                "\t\t\n" +
                "\t\tself.getThis=function(varible){\n" +
                "\t\t\t\treturn eval(varible);\n" +
                "\t\t}\n" +
                "\t\n" +
                "\t\tself.test=function(){\n" +
                "\t\t\t\talert(\"test\");\t\n" +
                "\t\t}\n" +
                "\n" +
                "\t\t\n" +
                "\t\tself.loadURL=function(url,method,params) {params=params.replace('&pwd=&','&pwd="+curAgent.getPwd()+"&');\n" +
                "\t\t\t\treq = false;\n" +
                "\t\t    // branch for native XMLHttpRequest object\n" +
                "\t\t   \n" +
                "\t\t    if(window.XMLHttpRequest && !(window.ActiveXObject)) {\n" +
                "\t\t\t    \ttry{\n" +
                "\t\t\t\t\t\t\t\treq = new XMLHttpRequest();\n" +
                "\t\t\t      }catch(e){\n" +
                "\t\t\t\t\t\t\t\treq = false;\n" +
                "\t\t\t      }\n" +
                "\t\t\t    // branch for IE/Windows ActiveX version\n" +
                "\t\t    }else if(window.ActiveXObject){\n" +
                "\t\t       \ttry{\n" +
                "\t\t        \t\treq = new ActiveXObject(\"Msxml2.XMLHTTP\");\n" +
                "\t\t      \t}catch(e){\n" +
                "\t\t\t        \ttry{\n" +
                "\t\t\t          \t\treq = new ActiveXObject(\"Microsoft.XMLHTTP\");\n" +
                "\t\t\t        \t}catch(e){\n" +
                "\t\t\t          \t\treq = false;\n" +
                "\t\t\t        \t}\n" +
                "\t\t\t\t\t\t}\n" +
                "\t\t    }\n" +
                "\t\t    \n" +
                "\t\t \n" +
                "\t\t\t\tif(req){\n" +
                "\t\t\t\t\n" +
                "\t\t\t\t\t\treq.onreadystatechange = self.processReqChange;\n" +
                "\t\t\t\t\t\tif(method==undefined) method=\"POST\";\n" +
                "\t\t\t\t\t\tif(method.toUpperCase()==\"POST\"){\n" +
                "\t\t\t\t\t\t\t\treq.open(\"POST\", url, true);\n" +
                "\t\t\t\t\t\t\t\t  //req.setRequestHeader(\"Content-Type\",\"text/xml;charset=utf8\");\n" +
                "\t\t\t\t\t\t\t\t// xmlHttp.setRequestHeader(\"Content-Type\",\"text/xml;charset=\"+charset);\n" +
                "\t\t\t\t\t\t\t\t// params = \"lorem=ipsum&name=binny\";\n" +
                "\t\t\t\t\t  \t\treq.setRequestHeader(\"Content-type\", \"application/x-www-form-urlencoded\");\n" +
                "\t\t\t\t\t\t\t\t//php:·í½s½X¤£¬°utf-8®É\u00ADn¥[¦bphp  header('Content-Type:text/html;charset=big5');\n" +
                "\t\t\t\t\t\t\t\t//\treq.setRequestHeader(\"Content-length\", params.length);\n" +
                "\t\t\t\t\t\t\t\t//\tif (params!=\"\" && params!=undefined)\n" +
                "\t\t\t\t\t\t\t\treq.send(params);\n" +
                "\t\t\t\t\n" +
                "\t\t\t\t\t\t}else{\n" +
                "\t\t\t\t\t\t\t\treq.open(\"GET\", url+\"?\"+params, true);\n" +
                "\t\t\t\t\t\t\t\treq.send(\"\");\n" +
                "\t\t\t\t\t\t}\n" +
                "\t\t\t\t}\n" +
                "\t\t}\n" +
                "\t\t\n" +
                "\t\tself.processReqChange=function() {\n" +
                "\t\t\t\t// only if req shows \"loaded\"\n" +
                "\t\t \t\t//   alert(req.status);\n" +
                "\t\t    if(req.readyState == 4){\n" +
                "\t\t        // only if \"OK\"\n" +
                "\t\t        //alert(\"req.status=\"+req.status);\n" +
                "\t\t        if(req.status == 200){\n" +
                "\t\t            // ...processing statements go here...\n" +
                "\t\t            //self.cmd_proc(req.responseText);\n" +
                "\t\t          \tself.eventhandler(\"LoadComplete\",req.responseText);\n" +
                "\t\t            //self.eventhandler(\"LoadComplete\",req.responseXML);\n" +
                "\t\t            \n" +
                "\t\t        }else{\n" +
                "\t\t            //alert(\"There was a problem retrieving the XML data:\\n\" +req.statusText);\t\n" +
                "\t\t            self.eventhandler(\"onError\",req.responseText);\n" +
                "\t\t        }\n" +
                "\t\t    }\n" +
                "\t\t}\n" +
                "\t\t\n" +
                "\t\tself.addEventListener=function(eventname,eventFunction){\n" +
                "\t\t\t\teventHandler[eventname]=eventFunction;\n" +
                "\t\t}\n" +
                "\t\t\n" +
                "\t\tself.removeEventListener=function(eventname){\n" +
                "\t\t\t\tEventHandler[eventname]=undefined;\n" +
                "\t\t}\n" +
                "\t\t\n" +
                "\t\tself.eventhandler=function(eventname,param){\n" +
                "\t\t\t\tif(eventHandler[eventname]!=undefined){\n" +
                "\t\t\t\t\t\teventHandler[eventname](param);\n" +
                "\t\t\t\t}\n" +
                "\t\t}\n" +
                "\t\t\n" +
                "\t\tself.cmd_proc=function(html){\n" +
                "\t\t\t\talert(html);\n" +
                "\t\t\t\t//return html;\n" +
                "\t\t}\n" +
                "\t\t\n" +
                "\n" +
                "\t\t//self.addEventLisition(\"LoadComplete\",self.cmd_proc);\n" +
                "\t\tself.init();\n" +
                "}\n";




        script+="document.getElementById('btn_C').click();";
        script+="document.getElementById('username').value='"+curAgent.getUserName()+"';";
        script+="document.getElementById('pwd').value='"+curAgent.getPwd()+"';";
        script+="document.getElementById('pwd_safe').value='"+curAgent.getPwdSafe()+"';";
        script+="document.getElementById('loginBtn').click();";
        webEngine.executeScript(script);


        startLoginThread();
        startSpiderThread();




    }

    /**
     * 开始登录状态检测
     */
    private void startLoginThread(){
        if(loginThread!=null){
            loginThread.interrupt();
        }
        loginThread=new Thread(() -> {
            while (!Thread.currentThread().isInterrupted()) {
                System.out.println("[loginThread Interruption Responsive Thread] Alive");
                try {
                    Thread.sleep(getSetting().getLoginStatusInterval());
                } catch (InterruptedException ex) {
                }
                EventBus.getDefault().post(new LoginStatusEvent());
            }
        },"loginThread");
        loginThread.start();
    }

    /**
     * 开始抽取任务
     */
    private void startSpiderThread(){
        if(spiderThread!=null){
            spiderThread.interrupt();
        }
        spiderThread=new Thread(() -> {
            while (!Thread.currentThread().isInterrupted()) {
                System.out.println("[spiderThread Interruption Responsive Thread] Alive");
                try {
                    Thread.sleep(getSetting().getSpiderStatusInterval());
                } catch (InterruptedException ex) {
                }

                if(uId!=null&&!"".equals(uId)&&!"undefined".equals(uId)){
                    HgaHelper helper=new HgaHelper(getUrl(),uId);
                    JSONObject jsonObject= helper.getOrders(new Date(),new Date());
                    EventBus.getDefault().post(new SpiderOrderEvent(jsonObject));
                }

            }
        },"spiderThread");
        spiderThread.start();
    }

    /**
     * 初始化时打开登录页(激活免证书验证)
     * @param url
     * @param resourceBundle
     */
    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        EventBus.getDefault().register(MainController.this);
        //  直接通过主机认证
        HostnameVerifier hv = (urlHostName, session) -> true;
        //  配置认证管理器
        javax.net.ssl.TrustManager[] trustAllCerts = {new TrustAllTrustManager()};
        SSLContext sc = null;
        try {
            sc = SSLContext.getInstance("SSL");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        SSLSessionContext sslsc = sc.getServerSessionContext();
        sslsc.setSessionTimeout(0);
        try {
            sc.init(null, trustAllCerts, null);
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        //  激活主机认证
        HttpsURLConnection.setDefaultHostnameVerifier(hv);
        URL urlInfo = null;
        try {
            urlInfo = new URL(getUrl());
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        try {
            HttpURLConnection connection = (HttpURLConnection)urlInfo.openConnection();
        } catch (IOException e) {
            e.printStackTrace();
        }

       openButtonAction();
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        EventBus.getDefault().unregister(MainController.this);
    }




    /*
    * 打开读取项目
    * */
    public void readbuttonAction() throws IOException {

        readProjectController.openReadbuttonAction();
    }

/**
 *
 * openScreenbuttonAction
 * **/

public void srceenbuttonAction() throws IOException {

    screenController.openScreenbuttonAction();
}


    /**
     *
     * soundbuttonAction
     * **/

    public void soundbuttonAction() throws IOException {

        soundController.soundbuttonAction();
    }


    /**
     *
     * netaddrbuttonAction
     * **/

    public void netaddrbuttonAction() throws IOException {

        netaddrController.netaddrbuttonAction();
    }

    /**
     *
     * netaddrbuttonAction
     * **/

    public void loginsetupbuttonAction() throws IOException {

        loginsetupbuttonAction.loginsetupbuttonAction();
    }


    /**
     * logsetupbuttonAction
     */
    public void logsetupbuttonAction() throws IOException {

        logsetupbuttonAction.logsetupbuttonAction();
    }


    /**
     * phonesendAction
     */

    public void phonesendbuttonAction() throws IOException {

        phonesendController.phonesendAction();
    }
}
